package com.tian.service.impl;

import com.tian.entity.ChargeUserPoint;
import com.tian.entity.PointsChangeRecord;
import com.tian.mapper.ChargeUserPointMapper;
import com.tian.mapper.PointsChangeRecordMapper;
import com.tian.message.ChargeUserPointMessage;
import com.tian.message.UserPointMessage;
import com.tian.service.UserPointService;
import com.tian.util.RedisConstantPre;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * {@code @description:} 用户积分
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-03-24 10:13
 * {@code @version:} 1.0
 */
@Slf4j
@Service
public class UserPointServiceImpl implements UserPointService {
    @Resource
    private ChargeUserPointMapper chargeUserPointMapper;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private PointsChangeRecordMapper pointsChangeRecordMapper;

    /**
     * 1：获取该用的分布式锁
     * 2：校验是否重复消费
     * 3：新增用户积分变更记录
     * 4：用户积分增加
     * 5：师范分布式锁
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUserPoint(UserPointMessage userPointMessage) {
        RLock lock = redissonClient.getLock(RedisConstantPre.USER_INFO_ID_LOCK_PRE + userPointMessage.getUserId());
        lock.lock();
        try {
            int count = pointsChangeRecordMapper.selectByReqId(userPointMessage.getReqId());
            if (count > 0) {
                log.info(" 用户积分新增 消息 【重复消费】:{}", userPointMessage);
                return;
            }
            PointsChangeRecord pointsChangeRecord = new PointsChangeRecord();
            pointsChangeRecord.setUserId(userPointMessage.getUserId());
            pointsChangeRecord.setPoint(userPointMessage.getPoint());
            pointsChangeRecord.setType(userPointMessage.getType());
            pointsChangeRecord.setCreateTime(new Date());
            pointsChangeRecord.setReqId(userPointMessage.getReqId());

            ChargeUserPoint chargeUserPoint = new ChargeUserPoint();
            chargeUserPoint.setUserId(userPointMessage.getUserId());
            chargeUserPoint.setPoint(userPointMessage.getPoint());
            //用户积分更新
            int result = chargeUserPointMapper.updatePointByUserId(chargeUserPoint);
            if (result != 1) {
                log.info("用户id:{}，更新用户积分失败", chargeUserPoint.getUserId());
                return;
            }
            //积分变动记录
            pointsChangeRecordMapper.insert(pointsChangeRecord);

        } finally {
            lock.unlock();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void initUserPoint(ChargeUserPointMessage chargeUserPointMessage) {
        ChargeUserPoint chargeUserPoint = chargeUserPointMapper.selectByUserId(chargeUserPointMessage.getUserId());
        if (chargeUserPoint != null) {
            return;
        }
        chargeUserPoint = new ChargeUserPoint();
        chargeUserPoint.setUserId(chargeUserPointMessage.getUserId());
        chargeUserPoint.setFreeze(0);
        chargeUserPoint.setPoint(chargeUserPointMessage.getPoint());
        chargeUserPoint.setStatus(0);
        chargeUserPoint.setUpdateTime(new Date());
        chargeUserPointMapper.insert(chargeUserPoint);
        if (chargeUserPointMessage.getPoint() > 0) {
            PointsChangeRecord pointsChangeRecord = new PointsChangeRecord();
            pointsChangeRecord.setUserId(chargeUserPointMessage.getUserId());
            pointsChangeRecord.setPoint(chargeUserPointMessage.getPoint());
            pointsChangeRecord.setType(0);
            pointsChangeRecord.setCreateTime(new Date());
            pointsChangeRecord.setReqId(chargeUserPointMessage.getReqId());
            //积分变动记录
            pointsChangeRecordMapper.insert(pointsChangeRecord);
        }
    }
}
